#include "prm.h"

void initPRM()
{
	//prmThread = malloc(sizeof(pthread_t));
	prmMailbox = malloc(sizeof(blockingQueue));
	mbox_init(prmMailbox);
	pthread_create(&prmThread,NULL,(void*)loadPageToMM,0);
}

void stopPRM()
{
	mbox_enqueue(prmMailbox,NULL);
	pthread_join(prmThread,NULL);
}

void loadPageToMM()
{
	int doExit = 0;
	while(!doExit)
	{
		pMessage_t * msg = mbox_dequeue(prmMailbox);
		if (msg != NULL)
		{
			writerStart();
			int processID = msg->vAddr;
			int pageNum = msg->offset;

			killMessage(msg);

			iptRecord iptRec;
			int mmPageIndex;

			mmPageIndex = getNextFreePageInMM();	//get next free page to override in MM
			iptRec = ipt[mmPageIndex];

			char* mmPage;	//Main memory page pointer
			char* diskPage;  //Disk memory page pointer

			//if page has changed, copy it from MM to Disk first
			if (iptRec.dirtyBit == 1)
			{
				//these pointers point to the current page in MM which needs to be copied to Disk
				mmPage = mmGetPage(mmPageIndex);	//get MM page pointer
				diskPage = diskGetPage(pcbGetProcessPageStartIndex(iptRec.pid)+iptRec.logicPageNum); //get Disk page pointer
				//printf("going to copy %c%c from mm to disk pid: %d page: %d \n", mmPage[0],mmPage[1],processID,mmPageIndex);
				memcpy(diskPage, mmPage, pageSize);
				//stringCopy(diskPage, mmPage, pageSize); //Copy page from the MM to the Disk
				//printDisk();
			}

			//Copy from Disk to MM
			//these pointers point to the current page in Disk which needs to be copied to the MM
			mmPage = mmGetPage(mmPageIndex);
			diskPage = diskGetPage(pcbGetProcessPageStartIndex(processID)+pageNum);
			//printf("going to copy %c%c from disk to mm pid: %d page: %d \n", diskPage[0],diskPage[1],processID,pageNum);
			memcpy(mmPage, diskPage, pageSize);
			//stringCopy(mmPage, diskPage, pageSize); //Copy page from the Disk to the MM
			insertIptRecord(processID, pageNum, mmPageIndex);
			sem_post(pcb[processID].waitForPRM);
			writerEnd();
		}
		else
			doExit = 1;

	}
}

void killPRM()
{
	mbox_kill(prmMailbox);
	//FREE(prmThread);
}

